/*DxfEntity.java
 *
 * Created on 5 de Dezembro de 2007, 15:23
 *
 * Modified on 08/10/2011, 02:00 PM by Adriano
 * Included the attribute @Override to inherited methods
 */

package importadorDXF;

import mathematics.Matrix4D;
import mathematics.Point3D;
import mathematics.Vector3D;

/**
 * @author rafaelbuck
 * @author Adriano Ferreira 
 */
public class DxfEntity implements DxfInterface, DxfConvertable, Dxf14Convertable
{    
    private String reference;
    private String ltype;
    private String layerName;
    private float height;
    private float extrusion;
    protected short color;
    private boolean tile;
    private Vector3D upward;
    private float ltScale;
    private boolean invisible;
    private boolean upwardIsZ;
    private boolean hasExpliciteZ;
    private DxfLAYER layer;
    
    /** Creates a new instance of DxfEntity */
    public DxfEntity()
    {
        color = -1;
        upward = new Vector3D(0.0F, 0.0F, 1.0F);
        ltScale = 1.0F;
        invisible = false;
    }
    
    protected void setCoord(Point3D pt, int dir, float val)
    {
        switch(dir)
        {
        case 1: // '\001'
            pt.x = val;
            break;

        case 2: // '\002'
            pt.y = val;
            break;

        case 3: // '\003'
            hasExpliciteZ = true;
            pt.z = val;
            break;
        }
    }

    protected void setCoord(Vector3D v, int dir, float val)
    {
        switch(dir)
        {
        case 1: // '\001'
            v.x = val;
            break;

        case 2: // '\002'
            v.y = val;
            break;

        case 3: // '\003'
            v.z = val;
            break;
        }
    }

    @Override
    public boolean setGroup(short grpNr, float fval)
    {
        switch(grpNr)
        {
        case 38: // '&'
            hasExpliciteZ = true;
            height = fval;
            return true;

        case 39: // '\''
            extrusion = fval;
            return true;

        case 48: // '0'
            ltScale = fval;
            return true;

        case 210: 
        case 220: 
        case 230: 
            setCoord(upward, (grpNr - 200) / 10, fval);
            return true;
        }
        return false;
    }

    @Override
    public boolean setGroup(short grpNr, short color)
    {
        if(grpNr == 62)
        {
            this.color = color;
            return true;
        } else
        {
            return false;
        }
    }

    @Override
    public boolean setGroup(short grpNr, int ival)
    {
        if(grpNr == 67)
        {
            tile = ival != 0;
            return true;
        } else
        {
            return false;
        }
    }

    @Override
    public boolean setGroup(short grpNr, String str)
    {
        switch(grpNr)
        {
        case 5: // '\005'
            reference = str;
            return true;

        case 6: // '\006'
            ltype = str;
            return true;

        case 8: // '\b'
            layerName = str;
            return true;

        case 100: // 'd'
            return true;
        }
        return false;
    }

    @Override
    public boolean finishRead(DxfFile file)
    {
        float len = upward.length();
        if(len != 1.0F)
            if(len != 0.0F)
                upward.scale(1.0F / len);
            else
                return false;
        upwardIsZ = upward.x == 0.0F && upward.y == 0.0F && upward.z > 0.0F;
        if(layerName == null)
            layerName = "0";
        layer = file.getLayer(layerName, true);
        return true;
    }

    boolean isTerm()
    {
        return false;
    }

    boolean isENDSEC()
    {
        return false;
    }

    boolean isBlockNamed(String name)
    {
        return false;
    }

    public final Matrix4D calcArbitMat()
    {
        if(upwardIsZ && height == 0.0F)
            return null;
        
        Vector3D row1;
        if((upward.x >= 0.0F ? upward.x : -upward.x) < 0.015625F && (upward.y >= 0.0F ? upward.y : -upward.y) < 0.015625F)
            row1 = new Vector3D(upward.z, 0.0F, -upward.x);
        else
            row1 = new Vector3D(-upward.y, upward.x, 0.0F);
        
        float len = row1.length();
        row1.scale(1.0F / len);
        Vector3D row2 = upward.cross(row1);
        Matrix4D aaa = new Matrix4D(row1.x, row2.x, upward.x, height * upward.x, row1.y, row2.y, upward.y, height * upward.y, row1.z, row2.z, upward.z, height * upward.z, 0.0F, 0.0F, 0.0F, 1.0F);
        
        return aaa;
    }

    public final String getReference()
    {
        return reference;
    }

    public final String getLayerName()
    {
        return layerName;
    }

    public final DxfLAYER getLayer()
    {
        return layer;
    }

    public final String getLtypeName()
    {
        return ltype != null ? ltype : "BYLAYER";
    }

    public final float getHeight()
    {
        return height;
    }

    public final float getExtrusion()
    {
        return extrusion;
    }

    public short getColor()
    {
        return color;
    }

    public final float getLtScale()
    {
        return ltScale;
    }

    public final boolean isInvisible()
    {
        return invisible;
    }

    public boolean getTile()
    {
        return tile;
    }

    public final Vector3D getUpwardVector()
    {
        return upward;
    }

    public final boolean upwardIsZ()
    {
        return upwardIsZ;
    }

    @Override
    public void convert(DxfConverter dxfconverter, DxfFile dxffile, Object obj)
    {
    }

    @Override
    public void convert(Dxf14Converter converter, DxfFile dxf, Object collector)
    {
        convert(((DxfConverter) (converter)), dxf, collector);
    }

    public DxfEntityCollector getEntityCollector()
    {
        return null;
    }

    void setExternalZ(float z)
    {
        if(!hasExpliciteZ)
            height = z;
    }
}